package com.didispace.web;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.*;

import java.util.Random;

@RestController
public class HelloController {

	private final Logger logger = Logger.getLogger(getClass());

	// 在主类 HelloApplication 中通过加上 @EnableDiscoveryClient 注解， 激活 Eureka 中的 DiscoveryClient 实现（
	// 自动化配置，创建 DiscoveryClient 接口针对 Eureka 客户端的 EurekaDiscoveryClient 实例），
	// 才能实现上述 Controller 中对服务信息的输出

// DiscoveryClient 是 Spring Cloud的接口， 它定义了用来发现服务的常用抽象方法， 通过该接口可以有效地 屏蔽服务治理的实现细节，
// 所以使用 Spring Cloud 构建的微服务应用可以方便地切换不同服务治理框架， 而不改动程序代码， 只需要另外添加一些针对服务治理框架的配置即可。

// EurekaClient 继承了 LookupService 接口， 它们都是 Netflix 开源包中的内容， 主要定义了针对 Eureka 的发现服务的抽象方法，
// 而真正实现发现服务的则是 Netflix 包中的 com.netflix.discovery.DiscoveryClient 类。

	@Autowired
	private DiscoveryClient client;

	@RequestMapping(value = "/hello", method = RequestMethod.GET)
	public String hello() throws Exception {
		ServiceInstance instance = client.getLocalServiceInstance();
		// 让处理线程等待几秒钟  测试超时触发断路器
		// int sleepTime = new Random().nextInt(3000);
		// logger.info("sleepTime:" + sleepTime);
		// Thread.sleep(sleepTime);

		logger.info("/hello, host:" + instance.getHost() + ", service_id:" + instance.getServiceId());
		return "Hello World";
	}

	@RequestMapping(value = "/hello1", method = RequestMethod.GET)
	public String hello(@RequestParam String name) {
		ServiceInstance instance = client.getLocalServiceInstance();
		logger.info("/hello1, host:" + instance.getHost() + ", service_id:" + instance.getServiceId());
		return "Hello " + name;
	}

	@RequestMapping(value = "/hello2", method = RequestMethod.GET)
	public User hello(@RequestHeader String name, @RequestHeader Integer age) {
		ServiceInstance instance = client.getLocalServiceInstance();
		logger.info("/hello2, host:" + instance.getHost() + ", service_id:" + instance.getServiceId());
		return new User(name, age);
	}

	@RequestMapping(value = "/hello3", method = RequestMethod.POST)
	public String hello(@RequestBody User user) {
		ServiceInstance instance = client.getLocalServiceInstance();
		logger.info("/hello3, host:" + instance.getHost() + ", service_id:" + instance.getServiceId());
		return "Hello "+ user.getName() + ", " + user.getAge();
	}

}

// 在hello-service服务控制台中，Tomcat启动之后，com.netflix.中scovery.DiscoveryClient 对象打印了该服务的注册信息 ，表示服务注册成功。
// 2022-04-29 10:02:35.542  INFO 1960 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8081 (http)
// 2022-04-29 10:02:35.543  INFO 1960 --- [           main] c.n.e.EurekaDiscoveryClientConfiguration : Updating port to 8081
// 2022-04-29 10:02:35.546  INFO 1960 --- [           main] com.didispace.HelloApplication           : Started HelloApplication in 15.744 seconds (JVM running for 18.244)
// 2022-04-29 10:02:35.556  INFO 1960 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient    : DiscoveryClient_HELLO-SERVICE/localhost:hello-service:8081 - registration status: 204


// http://localhost:8081/hello  通过访问http://localhost:8080/hello, 直接向该服务发起请求，在控制台中可以看到如下输出：
// 这些输出内容就是之前我们在 HelloController 中注入的 DiscoveryClient 接口对象， 从服务注册中心获取的服务相关信息。
// 2022-04-24 11:26:01.698  INFO 18916 --- [nio-8081-exec-1] com.didispace.web.HelloController        : /hello, host:localhost, service_id:hello-service

